﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using ElectricDim;
using YArchitech.Revit;

namespace HYRElectric.WirePlace
{
	internal class WireCollector
	{
		public double Length
		{
			get
			{
				return this.m_dLength;
			}
			set
			{
				this.m_dLength = value;
			}
		}

		public WireCollector(UIDocument uiDoc)
		{
			this.m_uiDoc = uiDoc;
			this.m_doc = uiDoc.Document;
		}

		private List<Element> CollectByType(Type type)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc, this.m_doc.ActiveView.Id);
			new List<Element>();
			if (filteredElementCollector != null)
			{
				filteredElementCollector.OfClass(type);
				return filteredElementCollector.ToList<Element>();
			}
			return null;
		}

		private CollecteWireResult CollectTargetWire()
		{
			if (this.m_lstWires != null)
			{
				this.m_lstWires.Clear();
				this.m_TargetWire = null;
			}
			List<Element> list = this.CollectByType(typeof(Wire));
			if (list == null || list.Count == 0)
			{
				TaskDialog.Show("CollectPoint", "没有导线，请检查文件是否正确");
				return CollecteWireResult.WithoutWire;
			}
			XYZ globalPoint = this.m_uiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new ChamferWireFilter(), "选择要打断的倒角导线").GlobalPoint;
			this.m_CollectPoint = new XYZ(globalPoint.X, globalPoint.Y, 0.0);
			double num = double.MaxValue;
			for (int i = 0; i < list.Count; i++)
			{
				Wire wire = list[i] as Wire;
				double num2 = 0.0;
				if (this.GetMinDistanceBetweenWireAndPoint(wire, this.m_CollectPoint, ref num2) && num2 <= this.Length)
				{
					this.m_lstWires.Add(wire);
					string b = wire.GetParameter(BuiltInParameter.RBS_ELEC_WIRE_TYPE).AsValueString();
					if (num2 < num && "倒角" == b)
					{
						this.m_TargetWire = wire;
						num = num2;
					}
				}
			}
			if (this.m_lstWires == null || this.m_lstWires.Count < 2)
			{
				TaskDialog.Show("CollectPoint", "所选取的点附近没有需要打断的倒角导线，请重新选择");
				return CollecteWireResult.WithoutPoint;
			}
			return CollecteWireResult.CollecteSuccess;
		}

		public bool GetMinDistanceBetweenWireAndPoint(Wire wire, XYZ xyzPoint, ref double dDistance)
		{
			Options options = new Options();
			options.ComputeReferences = true;
			options.View = this.m_doc.ActiveView;
			new HYElement(wire);
			double num = double.MaxValue;
			XYZ xyz = new XYZ(xyzPoint.X, xyzPoint.Y, 0.0);
			Parameter parameter = wire.GetParameter(BuiltInParameter.RBS_ELEC_WIRE_TYPE);
			string text = string.Empty;
			if (parameter == null || !parameter.HasValue)
			{
				return false;
			}
			text = parameter.AsValueString();
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			if (text == "弧" || text == "样条曲线导线")
			{
				return false;
			}
			if (text == "倒角")
			{
				int numberOfVertices = wire.NumberOfVertices;
				for (int i = 0; i < numberOfVertices - 1; i++)
				{
					XYZ vertex = wire.GetVertex(i);
					XYZ vertex2 = wire.GetVertex(i + 1);
					XYZ xyz2 = new XYZ(vertex.X, vertex.Y, 0.0);
					XYZ xyz3 = new XYZ(vertex2.X, vertex2.Y, 0.0);
					if (xyz2.DistanceTo(xyz3) >= 0.098425196850393692)
					{
						double num2 = Line.CreateBound(xyz2, xyz3).Distance(xyz);
						if (num2 < num)
						{
							num = num2;
						}
					}
				}
				dDistance = num;
				return true;
			}
			throw new Exception("导线类型未识别，请确认。");
		}

		private static int GetPointPositionIndexOnWire(List<XYZ> wirePoints, XYZ insertionPoint)
		{
			if (wirePoints == null || wirePoints.Count < 2)
			{
				return -2;
			}
			insertionPoint = YJKRevitTools.SetZToZero(insertionPoint);
			int result = -1;
			double num = 0.001;
			int count = wirePoints.Count;
			for (int i = 0; i < count - 1; i++)
			{
				XYZ xyz = YJKRevitTools.SetZToZero(wirePoints[i]);
				if (xyz.IsAlmostEqualTo(insertionPoint, num))
				{
					result = i - 1;
					break;
				}
				XYZ xyz2 = YJKRevitTools.SetZToZero(wirePoints[i + 1]);
				if (xyz2.IsAlmostEqualTo(insertionPoint, num))
				{
					result = i;
					break;
				}
				YJKLine hyline = new YJKLine(xyz, xyz2);
				if (hyline.IsPointOnLine(insertionPoint))
				{
					result = i;
					break;
				}
				if (i == 0 && hyline.IsPointOnLineExtension(insertionPoint))
				{
					XYZ xyz3 = xyz.Subtract(insertionPoint).Normalize();
					XYZ xyz4 = xyz2.Subtract(xyz).Normalize();
					if (xyz3.IsAlmostEqualTo(xyz4, num))
					{
						result = i - 1;
						break;
					}
					if (hyline.IsPointOnLine(insertionPoint))
					{
						result = i;
						break;
					}
				}
				if (i == count - 2)
				{
					if (hyline.IsPointOnLineExtension(insertionPoint))
					{
						XYZ xyz5 = insertionPoint.Subtract(xyz2).Normalize();
						XYZ xyz6 = xyz2.Subtract(xyz).Normalize();
						if (xyz5.IsAlmostEqualTo(xyz6, num))
						{
							result = i + 1;
							break;
						}
					}
					else if (hyline.IsPointOnLine(insertionPoint))
					{
						result = i;
						break;
					}
				}
			}
			return result;
		}

		private CollecteWireResult CollectIntersection()
		{
			List<XYZ> list = new List<XYZ>();
			foreach (Wire wire in this.m_lstWires)
			{
				if (wire != this.m_TargetWire)
				{
					List<XYZ> intersectPointBetweenWires = this.GetIntersectPointBetweenWires(this.m_TargetWire, wire);
					list.AddRange(intersectPointBetweenWires);
				}
			}
			if (list == null || list.Count == 0)
			{
				TaskDialog.Show("WireCollect", "所选点附近没有交点，请重新选择");
				return CollecteWireResult.WithoutPoint;
			}
			this.m_InterruptPoint = list[0];
			double num = this.m_CollectPoint.DistanceTo(list[0]);
			for (int i = 1; i < list.Count; i++)
			{
				if (num >= this.m_CollectPoint.DistanceTo(list[i]))
				{
					num = this.m_CollectPoint.DistanceTo(list[i]);
					this.m_InterruptPoint = list[i];
				}
			}
			if (num > this.Length)
			{
				this.m_InterruptPoint = null;
				TaskDialog.Show("WireCollect", "所选点附近没有合适的交点，请重新选择");
				return CollecteWireResult.WithoutPoint;
			}
			return CollecteWireResult.CollecteSuccess;
		}

		public List<XYZ> GetIntersectPointBetweenWires(Wire wire1, Wire wire2)
		{
			List<XYZ> list = new List<XYZ>();
			new List<YJKLine>();
			List<YJKLine> list2 = new List<YJKLine>();
			List<YJKLine> curvesFromWire = WireCollector.GetCurvesFromWire(wire1, true, this.m_CollectPoint);
			list2 = WireCollector.GetCurvesFromWire(wire2, false, null);
			foreach (YJKLine hyline in curvesFromWire)
			{
				foreach (YJKLine hyline2 in list2)
				{
					XYZ xyz = hyline.IntersectionPoint(hyline2.Line);
					if (xyz != null)
					{
						list.Add(xyz);
					}
				}
			}
			return list;
		}

		public static List<Curve> GetCurvesFromWire(Wire wire, Document doc)
		{
			List<Curve> list = new List<Curve>();
			string a = wire.GetParameter(BuiltInParameter.RBS_ELEC_WIRE_TYPE).AsValueString();
			new HYElement(wire);
			Options options = new Options();
			options.ComputeReferences = true;
			options.View = doc.ActiveView;
			if (a == "弧" || a == "样条曲线导线")
			{
				return null;
			}
			if (a == "倒角")
			{
				int numberOfVertices = wire.NumberOfVertices;
				for (int i = 0; i < numberOfVertices - 1; i++)
				{
					XYZ vertex = wire.GetVertex(i);
					XYZ vertex2 = wire.GetVertex(i + 1);
					XYZ xyz = new XYZ(vertex.X, vertex.Y, 0.0);
					XYZ xyz2 = new XYZ(vertex2.X, vertex2.Y, 0.0);
					if (xyz.DistanceTo(xyz2) >= 0.08)
					{
						Line item = Line.CreateBound(xyz, xyz2);
						list.Add(item);
					}
				}
				return list;
			}
			return null;
		}

		public static List<YJKLine> GetCurvesFromWire(Wire wire, bool beSelectedWire = false, XYZ collectPoint = null)
		{
			List<YJKLine> list = new List<YJKLine>();
			string a = wire.GetParameter(BuiltInParameter.RBS_ELEC_WIRE_TYPE).AsValueString();
			new HYElement(wire);
			Options options = new Options();
			options.ComputeReferences = true;
			options.View = wire.Document.ActiveView;
			if (a == "弧" || a == "样条曲线导线")
			{
				return null;
			}
			if (!(a == "倒角"))
			{
				return null;
			}
			int numberOfVertices = wire.NumberOfVertices;
			if (!beSelectedWire || collectPoint == null)
			{
				for (int i = 0; i < numberOfVertices - 1; i++)
				{
					XYZ vertex = wire.GetVertex(i);
					XYZ vertex2 = wire.GetVertex(i + 1);
					XYZ xyz = new XYZ(vertex.X, vertex.Y, 0.0);
					XYZ xyz2 = new XYZ(vertex2.X, vertex2.Y, 0.0);
					if (xyz.DistanceTo(xyz2) >= 0.08)
					{
						YJKLine item = new YJKLine(xyz, xyz2);
						list.Add(item);
					}
				}
				return list;
			}
			List<XYZ> chamferWireCtrlPoints = RevitVersionFuncs.GetChamferWireCtrlPoints(wire.Document, wire);
			int pointPositionIndexOnWire = WireCollector.GetPointPositionIndexOnWire(chamferWireCtrlPoints, YJKRevitTools.SetZToZero(collectPoint));
			if (pointPositionIndexOnWire < 0 || pointPositionIndexOnWire > chamferWireCtrlPoints.Count - 2)
			{
				return list;
			}
			XYZ vertex3 = wire.GetVertex(pointPositionIndexOnWire);
			XYZ vertex4 = wire.GetVertex(pointPositionIndexOnWire + 1);
			XYZ xyz3 = new XYZ(vertex3.X, vertex3.Y, 0.0);
			XYZ xyz4 = new XYZ(vertex4.X, vertex4.Y, 0.0);
			if (xyz3.DistanceTo(xyz4) < 0.08)
			{
				return list;
			}
			list.Add(new YJKLine(xyz3, xyz4));
			return list;
		}

		public CollecteWireResult ChoosePoint()
		{
			CollecteWireResult collecteWireResult = this.CollectTargetWire();
			if (collecteWireResult == CollecteWireResult.CollecteSuccess)
			{
				return this.CollectIntersection();
			}
			return collecteWireResult;
		}

		private UIDocument m_uiDoc;

		private Document m_doc;

		private XYZ m_CollectPoint = new XYZ();

		private List<Wire> m_lstWires = new List<Wire>();

		private double m_dLength;

		public Wire m_TargetWire;

		public XYZ m_InterruptPoint = new XYZ();
	}
}
